home *** CD-ROM | disk | FTP | other *** search
- { TransSkel multiple-window demonstration: Region module}
-
- { This module handles a window in which the mouse may be clicked and}
- { dragged to draw rectangles. The rects so drawn are combined into}
- { a single region, the outline of which is drawn. Rects drawn while}
- { the shift key is held down are subtracted from the region.}
- { Double-clicking the mouse clears the display. If the window is}
- { resized, the region that is drawn is resized as well.}
-
- { 14 June 1986 Paul DuBois}
-
- { Changes:}
- { 07/08/86 Changed outline so that it's drawn as a marquee.}
- { Ported to LightSpeed Pascal 7 January 1987 }
- { By Owen Hartnett, Ωhm Software }
-
- UNIT regionpas;
- INTERFACE
-
- USES
- transSkelpas, multiSkelGlobs, common;
-
- PROCEDURE RgnWindInit;
-
-
- IMPLEMENTATION
-
- VAR
- rgnPortRect : Rect; { portRect size - for detecting wind grows }
- selectRgn : RgnHandle; { current region to be drawn }
- selectWhen : longint; { time of last click }
- selectWhere : Point; { location of last click }
- marqueePat : Pattern;
-
- PROCEDURE Clobber;
-
- BEGIN
- DisposeRgn(selectRgn);
- CloseWindow(rgnWind);
- END;
-
- { While mouse is down, draw gray selection rectangle in the current}
- { port. Return the resultant rect in dstRect. The rect is always}
- { clipped to the current portRect.}
-
-
- PROCEDURE DoSelectRect (startPoint : point;
- VAR dstRect : Rect);
-
- VAR
- pt, dragPt : Point;
- rClip : Rect;
- thePort : GrafPtr;
- result : Boolean;
- ps : PenState;
- i : integer;
-
- BEGIN
- GetPort(thePort);
- rClip := thePort^.portRect;
- rClip.right := rClip.right - 15;
- GetPenState(ps);
- PenPat(gray);
- PenMode(patXor);
- dragPt := startPoint;
- Pt2Rect(dragPt, dragPt, dstRect);
- FrameRect(dstRect);
- WHILE StillDown DO
- BEGIN
- GetMouse(pt);
- IF NOT EqualPt(pt, dragPt) THEN { mouse has moved, change region }
- BEGIN
- FrameRect(dstRect);
- dragPt := pt;
- Pt2Rect(dragPt, startPoint, dstRect);
- result := SectRect(dstRect, rClip, dstRect);
- FrameRect(dstRect);
- FOR i := 0 TO 1000 DO
- ;
- END;
- END;
- FrameRect(dstRect); { erase last rect }
- SetPenState(ps);
- END;
-
- PROCEDURE MarqueeRgn (r : RgnHandle);
-
- VAR
- p : PenState;
- b : Byte;
- i : integer;
-
- BEGIN
- GetPenState(p);
- PenPat(marqueePat);
- PenMode(patCopy);
- FrameRgn(r);
- SetPenState(p);
- b := marqueePat[0]; { shift pattern for next call }
- FOR i := 0 TO 6 DO
- marqueePat[i] := marqueePat[i + 1];
- marqueePat[7] := b;
- END;
-
- PROCEDURE Idle;
-
- VAR
- i : integer;
-
- BEGIN
- SetWindClip(rgnWind);
- MarqueeRgn(selectRgn); { draw selection region outline }
- ResetWindClip; { restore previous clipping }
- END;
-
- { On double-click, clear window. On single click, draw gray selection}
- { rectangle as long as mouse is held down. If user draws non-empty rect,}
- { then add it to the selection region and redraw the region's outline.}
- { If the shift-key was down, then subtract the selection region instead}
- { and redraw.}
-
-
- PROCEDURE Mouse (thePt : Point;
- t : longint;
- mods : integer);
-
- VAR
- r : Rect;
- rgn : RgnHandle;
-
- BEGIN
- r := rgnWind^.portRect;
- IF thePt.h < r.right - 15 THEN { must not click in right edge }
- BEGIN
- IF (t - selectWhen <= GetDblTime) THEN { it's a double-click }
- BEGIN
- selectWhen := 0; { don't take next click as dbl-click }
- SetWindClip(rgnWind);
- EraseRgn(selectRgn);
- ResetWindClip;
- SetEmptyRgn(selectRgn); { clear region }
- END
- ELSE
- BEGIN
- selectWhen := t; { update click variables }
- selectWhere := thePt;
- DoSelectRect(thePt, r); { draw selection rectangle }
- IF NOT EmptyRect(r) THEN
- BEGIN
- EraseRgn(selectRgn);
- selectWhen := 0;
- rgn := NewRgn;
- RectRgn(rgn, r);
- IF (Bitand(mods, shiftKey)) <> 0 THEN { test shift key }
- DiffRgn(selectRgn, rgn, selectRgn)
- ELSE
- unionRgn(selectRgn, rgn, selectRgn);
- DisposeRgn(rgn);
- END;
- END;
- END;
- END;
-
- { Redraw the current region. If the window was resized, resize}
- { the region to fit.}
-
- PROCEDURE Update (resized : Boolean);
-
- VAR
- r : Rect;
-
- BEGIN
- EraseRect(rgnWind^.portRect);
- IF resized THEN
- BEGIN
- r := rgnWind^.portRect;
- rgnPortRect.right := rgnPortrect.right - 15; { don't use right edge of window }
- r.right := r.right - 15;
- MapRgn(selectRgn, rgnPortRect, r);
- rgnPortRect := rgnWind^.portRect
- END;
- DrawGrowBox(rgnWind);
- idle;
- END;
-
- PROCEDURE Activate (active : Boolean);
-
- BEGIN
- DrawGrowBox(rgnWind);
- IF active THEN
- DisableItem(editMenu, 0)
- ELSE
- EnableItem(editMenu, 0);
- DrawMenuBar;
- END;
-
- PROCEDURE RgnWindInit;
-
- BEGIN
- StuffHex(@marqueePat, '0f87c3e1f0783c1e');
- rgnWind := GetNewWindow(rgnWindRes, NIL, WindowPtr(-1));
- SkelWindow(rgnWind, @Mouse, NIL, @update, @activate, NIL, @Clobber, @Idle, true);
- { ignore keyclicks }
- { no close proc }
- { disposal proc }
- { idle proc }
-
- rgnPortRect := rgnWind^.portRect;
- selectRgn := NewRgn; { selected region empty initially }
-
- selectWhen := 0; { first click can't be taken as dbl-click }
- END;
-
-
-
- END.